package com.google.code.chaotic.client.ui;

import static com.google.code.chaotic.client.Constants.DEFAULT_MAP_CENTER;
import static com.google.code.chaotic.client.Constants.DEFAULT_ZOOM_LEVEL;
import static com.google.code.chaotic.client.Constants.LIGHT_BLUE;
import static com.google.code.chaotic.client.Constants.KHAKI;

import java.util.List;

import com.allen_sauer.gwt.log.client.Log;
import com.google.code.chaotic.client.ClientSessionManager;
import com.google.code.chaotic.client.ui.ProfileDetailsPanel.State;
import com.google.code.chaotic.dto.AdminDto;
import com.google.code.chaotic.dto.CommuterDto;
import com.google.code.chaotic.dto.LatLonDto;
import com.google.code.chaotic.dto.UserDto;
import com.google.code.chaotic.rpc.AuthSvc;
import com.google.code.chaotic.rpc.AuthSvcAsync;
import com.google.code.chaotic.rpc.CommuterSvc;
import com.google.code.chaotic.rpc.CommuterSvcAsync;
import com.google.code.chaotic.rpc.JavaSvc;
import com.google.code.chaotic.rpc.JavaSvcAsync;
import com.google.code.chaotic.rpc.ServiceSvc;
import com.google.code.chaotic.rpc.ServiceSvcAsync;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.user.client.ui.Widget;

public class ChaosPanel extends Composite {

	/**
	 * Creating remote services' proxies to talk to the server-side services.
	 */
	private final AuthSvcAsync authSvc = GWT.create(AuthSvc.class);
	private final CommuterSvcAsync commuterSvc = GWT.create(CommuterSvc.class);
	private final ServiceSvcAsync serviceSvc = GWT.create(ServiceSvc.class);
	private final JavaSvcAsync javaSvc = GWT.create(JavaSvc.class);

	//

	private ProfileDetailsPanel profilePanel = new ProfileDetailsPanel();
	private ServiceMgmtPanel serviceMgmtPanel = new ServiceMgmtPanel();

	//

	private DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.EM);
	private DockLayoutPanel headerPanel = new DockLayoutPanel(Unit.PCT);
	private SimplePanel contentPanel = new SimplePanel();
	private SimplePanel footerPanel = new SimplePanel();

	private FlowPanel logosPanel = new FlowPanel();
	private Image logo = new Image("/images/chaos-logo.png");
	private Image logoDesc = new Image("/images/chaos-desc.png");

	private DockLayoutPanel menuAndLinks = new DockLayoutPanel(Unit.EM);
	private FlowPanel cornerLinks = new FlowPanel();
	private HTML userLabel = new HTML("Anonymous user!");
	private Anchor logoutAnchor = new Anchor("Sign out");

	private MenuBar menuBar = new MenuBar();
	private TabLayoutPanel tabPanel = new TabLayoutPanel(2.4, Unit.EM);

	//

	public ChaosPanel() {
		initWidget(mainPanel);

		Label linkSeparator = new Label(" | ");

		mainPanel.addNorth(headerPanel, 4.5);
		mainPanel.addSouth(footerPanel, 4);
		mainPanel.add(contentPanel);

		headerPanel.addWest(logosPanel, 60);
		headerPanel.add(menuAndLinks);

		logosPanel.add(logo);
		logosPanel.add(logoDesc);

		menuAndLinks.addNorth(cornerLinks, 3);
		cornerLinks.add(logoutAnchor);
		cornerLinks.add(linkSeparator);
		cornerLinks.add(userLabel);

		// Widget footerWidget = createFooter();
		HTML footerWidget = getFooterHtml();
		footerPanel.setWidget(footerWidget);

		profilePanel.getElement().getStyle().setOverflow(Overflow.AUTO);

		contentPanel.setWidget(tabPanel);
		tabPanel.add(serviceMgmtPanel, createTabHtml("Service Management"),
				true);
		tabPanel.add(new Label(), createTabHtml("Fleet Management"), true);

		//

		headerPanel.getElement().getStyle().setBackgroundColor(LIGHT_BLUE);
		profilePanel.getElement().getStyle().setBackgroundColor(KHAKI);

		Style logoStyle = logo.getElement().getStyle();
		Style logoDescStyle = logoDesc.getElement().getStyle();

		logoStyle.setMargin(1, Unit.EM);
		logoDescStyle.setMargin(1, Unit.EM);
		logoDescStyle.setPaddingLeft(0, Unit.EM);

		Style userLabelStyle = userLabel.getElement().getStyle();
		Style linkSeparatorStyle = linkSeparator.getElement().getStyle();
		Style logoutAnchorStyle = logoutAnchor.getElement().getStyle();

		userLabelStyle.setFontWeight(FontWeight.BOLD);

		userLabelStyle.setFloat(Float.RIGHT);
		linkSeparatorStyle.setFloat(Float.RIGHT);
		logoutAnchorStyle.setFloat(Float.RIGHT);

		userLabelStyle.setPadding(0.5, Unit.EM);
		linkSeparatorStyle.setPadding(0.5, Unit.EM);
		logoutAnchorStyle.setPadding(0.5, Unit.EM);

		cornerLinks.getElement().getStyle().setPadding(0.5, Unit.EM);
		footerPanel.getElement().getStyle().setMarginTop(1, Unit.EM);

		//

		mainPanel.setSize("100%", "100%");
		tabPanel.setSize("100%", "100%");

		// Window.addResizeHandler(new ResizeHandler() {
		// @Override
		// public void onResize(ResizeEvent event) {
		// maximize();
		// }
		// });

		logoutAnchor.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				authSvc.logout(ClientSessionManager.getId(),
						new AsyncCallback<Void>() {
							@Override
							public void onSuccess(Void result) {
								Window
										.open( //
												GWT.getHostPageBaseURL()
														+ "Login.html", //
												"_self", "");
							}

							@Override
							public void onFailure(Throwable th) {
								Log.error(th.toString(), th);
							}
						});
			}
		});
	}

	private String createTabHtml(String tabText) {
		return "<span style='font-size: 1.2em;'>" + tabText + "</span>";
	}

	@Override
	protected void onLoad() {
		super.onLoad();

		UserDto user = ClientSessionManager.getInstance().getUserNoPass();
		applyUser(user);
	}

	private void applyUser(UserDto user) {
		userLabel.setText(user.getFirstName() + " " + user.getLastName());
		tabPanel.clear();
		if (user instanceof CommuterDto) {
			tabPanel.add(serviceMgmtPanel, "Service Matches");
			CommuterDto commuter = (CommuterDto) user;
			profilePanel.setCommuter(commuter);
			profilePanel.setState(State.UPDATE);
			tabPanel.add(profilePanel, "View/Edit Profile");

		} else if (user instanceof AdminDto) {
			tabPanel.add(serviceMgmtPanel, "Service Management");
		}
	}

	@Deprecated
	private Widget createFooter() {
		FlowPanel footer = new FlowPanel();
		FlowPanel linksPanel = new FlowPanel();
		// linksPanel.setSpacing(10);
		Label label = new Label(
		// TODO: Must be changed.
				"Temporary links for development and debugging purposes:");
		final Anchor origsAnchor = new Anchor("Origins Overview");
		final Anchor destsAnchor = new Anchor("Destinations Overview");

		ClickHandler handler = new OrigDestClickHandler( //
				destsAnchor, origsAnchor);
		origsAnchor.addClickHandler(handler);
		destsAnchor.addClickHandler(handler);

		label.getElement().getStyle().setFloat(Float.LEFT);
		origsAnchor.getElement().getStyle().setFloat(Float.LEFT);
		destsAnchor.getElement().getStyle().setFloat(Float.LEFT);

		label.getElement().getStyle().setMarginLeft(4, Unit.EM);
		origsAnchor.getElement().getStyle().setMarginLeft(4, Unit.EM);
		destsAnchor.getElement().getStyle().setMarginLeft(4, Unit.EM);

		linksPanel.getElement().getStyle().setMargin(0.6, Unit.EM);

		linksPanel.add(label);
		linksPanel.add(origsAnchor);
		linksPanel.add(destsAnchor);

		footer.add(linksPanel);
		footer.setWidth("100%");
		return footer;
	}

	public static HTML getFooterHtml() {
		String baseURL = GWT.getHostPageBaseURL();
		HTML footerHtml = new HTML("<div"//
				+ " style='background-color: #B7CBE8;"
				+ " padding: 1em; text-align: center;"
				+ " vertical-align: bottom;'>" //
				+ "©2010 <span" //
				+ "	style='font-family: sans-serif;" //
				+ " font-style: italic;'>CHAOS</span> Group" //
				+ " - <a href='" + baseURL + "terms.html'>Terms</a>" //
				+ " - <a href='" + baseURL + "privacy.html'>" //
				+ "Privacy Policy</a>" //
				+ " - <a href='" + baseURL + "support'>Help</a></div>");
		return footerHtml;
	}

	private final class OrigDestClickHandler implements ClickHandler {
		final Anchor destsAnchor;
		final Anchor origsAnchor;

		private OrigDestClickHandler(Anchor destsAnchor, Anchor origsAnchor) {
			this.destsAnchor = destsAnchor;
			this.origsAnchor = origsAnchor;
		}

		@Override
		public void onClick(ClickEvent event) {
			Object source = event.getSource();
			MapWidget mapWidget = new MapWidget();
			final BulkMarkersViewer dialog = new BulkMarkersViewer(mapWidget);
			dialog.center();
			mapWidget.setCenter(DEFAULT_MAP_CENTER, DEFAULT_ZOOM_LEVEL);
			if (source == origsAnchor) {
				dialog.setText("Origins of Commuting Habits");
				dialog.setDescription( //
						"The markers below show the origins of "
								+ "collected commuting routes.");
				commuterSvc.listAllHabitOrigins(
						//
						ClientSessionManager.getId(),
						new AsyncCallback<List<LatLonDto>>() {

							@Override
							public void onFailure(Throwable th) {
								Log.error(th.getMessage(), th);
							}

							@Override
							public void onSuccess(List<LatLonDto> dtos) {
								dialog.markAll(dtos);
							}
						});

			} else if (source == destsAnchor) {
				dialog.setText("Destinations of Commuting Habits");
				dialog.setDescription( //
						"The markers below show the destinations of "
								+ "collected commuting routes.");
				commuterSvc.listAllHabitDestinations(
						//
						ClientSessionManager.getId(),
						new AsyncCallback<List<LatLonDto>>() {
							@Override
							public void onFailure(Throwable th) {
								Log.error(th.getMessage(), th);
							}

							@Override
							public void onSuccess(List<LatLonDto> dtos) {
								dialog.markAll(dtos);
							}
						});

			}
		}
	}
}
